const std = @import("std");
const maxInt = std.math.maxInt;
const curses = @cImport({
	@cInclude("curses.h");
});

const game = @import("game.zig");
const Grid = @import("grid.zig").Grid;
const Snake = @import("snake.zig").Snake;

const GRID_WIDTH: u8 = 10;
const GRID_HEIGHT: u8 = 10;
const START_POS: [2]u8 = .{
	GRID_WIDTH / 2,
	GRID_HEIGHT / 2,
};


pub fn main() !void {
	if (
			GRID_WIDTH == 0 or GRID_WIDTH == maxInt(u8)
			or GRID_HEIGHT == 0 or GRID_HEIGHT == maxInt(u8)
	) {
		const stdout = std.io.getStdOut().writer();
		try stdout.print("Invalid grid size\n", .{});
		return;
	}

	const window: *curses.struct__win_st = setup_curses() orelse {
		const stderr = std.io.getStdErr().writer();
		try stderr.print("Error: Failed to initialize window\n", .{});
		reset_curses();
		return;
	};
	defer reset_curses();

	while (true) {
		var snake = Snake{};
		try snake.init(START_POS);
		defer snake.deinit();

		var grid = Grid{
			.width = GRID_WIDTH,
			.height = GRID_HEIGHT,
			.window = window,
		};
		try grid.init();
		defer grid.deinit();

		try game.main_loop(&grid, &snake);
	}
}


fn setup_curses() ?*curses.struct__win_st {
	const window: ?*curses.struct__win_st = curses.initscr();
	_ = curses.cbreak();
	_ = curses.noecho();
	_ = curses.start_color();
	curses.timeout(0);

	_ = curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK);
	_ = curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK);
	_ = curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK);
	_ = curses.attron(curses.COLOR_PAIR(1));

	return window;
}


fn reset_curses() void {
	curses.timeout(-1);
	_ = curses.nocbreak();
	_ = curses.echo();
	_ = curses.endwin();
}


test "run tests" {
	_ = @import("tests/main.zig");
}
